package com.hc.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
 * 
* @Description: Redis连接池 
* @author   
* @date 2016年10月20日 下午5:05:48  
*
 */
public class RedisUtil {
    
    //Redis服务器IP
    private static String ADDR = "192.168.0.116";
    //Redis的端口号
    private static int PORT = 6379;
    
    //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
    private static int MAX_ACTIVE = -1;
    
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
    private static int MAX_IDLE = 200;
    
    //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
    private static int MAX_WAIT = 10000;
    
    private static int TIMEOUT = 10000;
    
    //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
    private static boolean TEST_ON_BORROW = true;
    
    private static JedisPool jedisPool = null;
    
    /**
     * 
     * @Description：Jedis链接池
     * @return
     * @author:  
     * @since: 2016年10月20日 下午5:06:09
     */
    public static JedisPool getPool() {  
        if (jedisPool == null) {  
            JedisPoolConfig config = new JedisPoolConfig();  
            //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；  
            //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。  
            config.setMaxTotal(MAX_ACTIVE);
            //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。  
            config.setMaxIdle(MAX_IDLE);
            //表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；  
            config.setMaxWaitMillis(MAX_WAIT); 
            //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；  
            config.setTestOnBorrow(TEST_ON_BORROW);
            try{
            	 jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT);
            } catch (Exception e) {
				LoggerUtil.error(e);
				System.err.println("链接Redis失败");
			}
           
        }  
        return jedisPool;  
    }  
      
    /** 
     * 返还到连接池 
     *  
     * @param pool  
     * @param redis 
     */  
    public static void returnResource(Jedis redis) {  
        if (redis != null) {  
            redis.close();  
        }  
    }     
    /**
     * 获取Jedis实例
     * @return
    */
    public static Jedis getJedis(){   
        JedisPool pool = null;  
        Jedis jedis = null;  
        try {  
            pool = getPool();
            if (pool==null){
            	return null;
            } 
            jedis = pool.getResource();  
        } catch (Exception e) {  
            //释放redis对象  
        	if(null != jedis)
        	jedis.close();  
            jedis=null;
            LoggerUtil.error(e);
        }        
        return jedis;  
    }  

    /**
     * 序列化工具
     * @param obj
     * @return
     */
    public static byte[] serialize(Object obj){
    	ObjectOutputStream oos = null;
    	ByteArrayOutputStream baos = null;
    	try{
    		baos = new ByteArrayOutputStream();
    		oos = new ObjectOutputStream(baos);
    		oos.writeObject(obj);
    		byte[] bytes = baos.toByteArray();
    		return bytes;
    	} catch (Exception e) {
    		LoggerUtil.error(e);
    	} finally {
			try {
				oos.close();
				baos.close();
			} catch (IOException e) {
				LoggerUtil.error(e);
			}
		}
		return null;
    }
    /**
     * 反序列化
     * @param bytes
     * @return
     */
    public static Object unserialize(byte[] bytes){
    	ByteArrayInputStream bais = null;
    	ObjectInputStream oi = null;
    	Object obj = null;
    	if (bytes==null){
    		return null;
    	}
    	try{
    		bais = new ByteArrayInputStream(bytes);
    		oi = new ObjectInputStream(bais);
    		obj =  oi.readObject();
    	}catch (Exception e) {
    		LoggerUtil.error(e);
		}finally {
			try {
				bais.close();
				oi.close();
			} catch (IOException e) {
				LoggerUtil.error(e);
			}
		}
		return obj;
    }
}
